/*
Copyright SecureKey Technologies Inc. All Rights Reserved.

SPDX-License-Identifier: Apache-2.0
*/
package endpoint

import (
	"encoding/pem"
	//"fmt"
	"io/ioutil"
	"regexp"
	"strings"

	x509GM "github.com/tjfoc/gmsm/x509"

	"github.com/pkg/errors"
)

// IsTLSEnabled 是否开启tls
func IsTLSEnabled(url string) bool {
	tlsURL := strings.ToLower(url)
	if strings.HasPrefix(tlsURL, "https://") || strings.HasPrefix(tlsURL, "grpcs://") {
		return true
	}
	return false
}

// ToAddress 在grpc地址中获取ip地址
func ToAddress(url string) string {
	if strings.HasPrefix(url, "grpc://") {
		return strings.TrimPrefix(url, "grpc://")
	}
	if strings.HasPrefix(url, "grpcs://") {
		return strings.TrimPrefix(url, "grpcs://")
	}
	return url
}

// AttemptSecured 是否开启加密，allowInSecure为true则开启 或者地址为grpcs则开启
func AttemptSecured(url string, allowInSecure bool) bool {
	ok, err := regexp.MatchString(".*(?i)s://", url)
	if ok && err == nil {
		return true
	} else if strings.Contains(url, "://") {
		return false
	} else {
		return !allowInSecure
	}
}

type MutualTLSConfig struct {
	Pem  []string
	Path string

	Client TLSKeyPair
}

type TLSKeyPair struct {
	Key  TLSConfig
	Cert TLSConfig
}

type TLSConfig struct {
	Path  string
	Pem   string
	bytes []byte
}

func (cfg *TLSConfig) Bytes() []byte {
	return cfg.bytes
}

func (cfg *TLSConfig) LoadBytes() error {
	var err error
	if cfg.Pem != "" {
		cfg.bytes = []byte(cfg.Pem)

	} else if cfg.Path != "" {
		cfg.bytes, err = ioutil.ReadFile(cfg.Path)
		if err != nil {
			return errors.Wrapf(err, "failed to load pem bytes from path %s", cfg.Path)
		}
	}
	return nil
}

// TLSCert pem转为tls证书
// @return *x509GM.Certificate
// @return bool
// @return error
func (cfg *TLSConfig) TLSCert() (*x509GM.Certificate, bool, error) {
	block, _ := pem.Decode(cfg.bytes)
	if block != nil {
		pub, err := x509GM.ParseCertificate(block.Bytes)
		if err != nil {
			return nil, false, errors.Wrap(err, "certificate parsing failed")
		}

		return pub, true, nil
	}
	return nil, false, nil
}
